library zdaolib32;

{$mode objfpc}{$H+}

uses

  { LCL Units }
  {{$IFNDEF LINUX}
  cthreads,
  {$ENDIF}}
  Classes,
  SysUtils,
  db,

  { ZEOS Units }
  ZPooling,
  ZConnection,
  ZAbstractDataset,
  ZAbstractRODataset,
  ZDataset,

  { Norsenet Units }
  nncrypt32,
  zdaotypes, zdaofunctions;

var
  zpInternalPool: TZDAOPooling;

procedure SetConnectionProperties(AConnection: TZConnection; AServer, AProtocol,
  ADatabase, AUser, APassword: WideString; APort: Word);
begin
  with AConnection do
  begin
    HostName := AServer;
    Protocol := AProtocol;
    Database := ADatabase;
    User := AUser;
    Password := APassword;
    Port := APort;
  end;
end;

function ExecSQL(ASQL, AServer, AProtocol, ADatabase, AUser, APassword, AResultSet: WideString;
  APort: Word): Integer; overload; stdcall;
var
  i: Byte;
  rXMLResult: TXMLSQResult;
begin
  Result := 0;
  with TZReadOnlyQuery.Create(nil) do
  begin
    Connection := zpInternalPool.Pooling.GetConnection;
    SetConnectionProperties(Connection, AServer, AProtocol, ADatabase, AUser, APassword, APort);
    SQL.Text := ASQL;

    try
      try
        ExecSQL;

        Result := RecordCount;

        if RecordCount > 0 then
        begin
          rXMLResult := TXMLSQResult.Create;

          case FieldCount of
            0: Result := -2;
            1: rXMLResult.AddHeader(Fields[0].Name, FieldType(Fields[0].DataType),
                                    IntToStr(Fields[0].Size), True, True);
          else
            for i := 0 to FieldCount - 1 do
            begin
              if i = 0 then
                rXMLResult.AddHeader(Fields[i].Name, FieldType(Fields[i].DataType),
                                     IntToStr(Fields[i].Size), True, False);

              if i = (FieldCount - 1) then
                rXMLResult.AddHeader(Fields[i].Name, FieldType(Fields[i].DataType),
                                     IntToStr(Fields[i].Size), False, True);

              rXMLResult.AddHeader(Fields[i].Name, FieldType(Fields[i].DataType),
                                   IntToStr(Fields[i].Size), True, True);
            end;

            rXMLResult.OpenData;

            First;

            while not Eof do
            begin
              case FieldCount of
                1: rXMLResult.AddRecordField(Fields[0].Name, ConvertData(Fields[0].DataType,
                                                                         Fields[0].Value),
                                             True, True);
              else
                for i := 0 to FieldCount - 1 do
                begin
                  if i = 0 then
                    rXMLResult.AddRecordField(Fields[i].Name, ConvertData(Fields[i].DataType,
                                                                          Fields[i].Value),
                                              True, False);

                  if i = (FieldCount - 1) then
                    rXMLResult.AddRecordField(Fields[i].Name, ConvertData(Fields[i].DataType,
                                                                          Fields[i].Value),
                                              False, True);

                  rXMLResult.AddRecordField(Fields[i].Name, ConvertData(Fields[i].DataType,
                                                                        Fields[i].Value),
                                            False, False);
                end;
              end;
              Next;
            end;

            rXMLResult.CloseData;
          end;
        end
        else
          begin
            rXMLResult.OpenData;

            case FieldCount of
              1: rXMLResult.AddRecordField(Fields[0].Name, '', True, True);
            else
              for i := 0 to FieldCount - 1 do
              begin
                if i = 0 then
                  rXMLResult.AddRecordField(Fields[i].Name, '', True, False);

                if i = (FieldCount - 1) then
                  rXMLResult.AddRecordField(Fields[i].Name, '', False, True);

                rXMLResult.AddRecordField(Fields[i].Name, '', False, False);
              end;
            end;
            rXMLResult.CloseData;
          end;
      except
        Result := -1;
      end;
    finally
      AResultSet := rXMLResult.XMLResult;
      FreeAndNil(rXMLResult);
      zpInternalPool.Pooling.ReturnConnection(Connection);
      Free;
    end;
  end;
end;



begin
  zpInternalPool := TZDAOPooling.Create;
end.

